通过 DNS 服务获取域名对应 Host

在编写 TCP/HTTP 客户端请求程序时,通过 DNS 服务获取域名对应的 IP 地址是非常常见的需求。

针对这一需求,在使用 Rust 进行开发时,我们主要有两种方式来实现。

标准库

Rust 的 stdnet 标准库中有一个名为 ToSocketAddrs 的 trait,它可以将表示主机地址的字符串转化为 SocketAddr 的迭代器,也可以对域名调用操作系统的 DNS 查询函数获取对应的 IP 地址,同样返回 SocketAddr 的迭代器。

tokio 的内部使用此方式实现 DNS 查询。见此文件183行

重要

使用 ToSocketAddrs 解析主机地址时必须带上端口,如

"127.0.0.1:4000".to_socket_addrs();
"localhost:4000".to_socket_addrs();
"google.com:80".to_socket_addrs();

你也可以使用 IP/域名 + 端口 的元组来解析,像这样:

("127.0.0.1", 4000).to_socket_addrs();
("localhost", 4000).to_socket_addrs();
("google.com", 80).to_socket_addrs();

操作系统 C 库

Rust 具备调用 C 库的能力,在库dns-lookup的源码中,其调用了操作系统的 getaddrinfo 函数。

如果你使用 C 语言进行过 socket 网络编程,你对 gethostbyname 这个函数应该不陌生。

根据 StackOverflow 上的这篇帖子gethostbyname()gethostbyaddr() 这两个函数不被鼓励使用,因为它们并不具备对 IPv6 的支持。而 getaddrinfo()getnameinfo() 正对应着上文的两个函数,并且它们支持 IPv6。

点此查看原文